package com.arpa.ntocc.common.common.util;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.arpa.ntocc.common.common.constant.StrConsts;
import com.arpa.ntocc.common.domain.entity.PartyGroupConfig;
import com.arpa.ntocc.common.service.IPartyGroupConfigService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.obs.services.ObsClient;
import com.obs.services.exception.ObsException;
import com.obs.services.model.*;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * 华为OBS工具类
 * @Author liuyj
 * @Date 2019-12-10 14:29:17
 */
@Log4j2
@Component
public class OBSUtil {

    @Autowired
    IPartyGroupConfigService partyGroupConfigService;

    /** Access Key **/
    private static String ak;
    /** Secret Access Key **/
    private static String sk;
    /** bucket名称 **/
    private static String bucketName;
    /** 终端节点 **/
    private static String endPoint;

    /**
     * obs客户端
     * 如果是全局ObsClient实例，可以不在每个方法调用完成后关闭
     * ObsClient在调用ObsClient.close方法关闭后不能再次使用
     **/
    private static ObsClient obsClient;

    /**
     * 初始化配置
     */
    @PostConstruct
    public void initConfig() {
        try {
            List<PartyGroupConfig> configList = partyGroupConfigService.list(new QueryWrapper<PartyGroupConfig>().lambda().eq(PartyGroupConfig::getType,"OBS"));
            if(CollectionUtils.isEmpty(configList)){
                log.error(LogUtil.log("++华为OBS配置缺失，请检查配置。++"));
            }
            for(PartyGroupConfig config:configList){
                switch (config.getConfigKey()){
                    case "ak": ak=config.getConfigValue(); break;
                    case "sk": sk=config.getConfigValue(); break;
                    case "bucketName": bucketName=config.getConfigValue(); break;
                    case "endPoint": endPoint=config.getConfigValue(); break;
                    default:
                }
            }
            // 创建ObsClient实例
            obsClient = new ObsClient(ak, sk, endPoint);

        } catch (Exception e) {
           log.error(StrConsts.CATCH_MESSAGE,e);
        }
    }

    /**
     * 上传文件
     *
     * @param myFile
     */
    public static String uploadFile(MultipartFile myFile) throws ObsException, IOException {
        if( null==myFile ){
            return "";
        }
        String filePath="";
        try {
            String key = generateFileKey(myFile);

            ObjectMetadata objectMeta = new ObjectMetadata();
            objectMeta.setContentLength(myFile.getSize());
            // 可以在metadata中标记文件类型
            objectMeta.setContentType(myFile.getContentType());

            HeaderResponse response = obsClient.putObject(bucketName, key, myFile.getInputStream());
            filePath = getFilePath(key);
            log.info(LogUtil.log("upFile","上传obs文件："+filePath));
        }catch (Exception e) {
            log.error(StrConsts.CATCH_MESSAGE,e);
        }
        return filePath;
    }

    /**
     * 生成文件唯一key
     * @param myFile
     */
    private static String generateFileKey(MultipartFile myFile){
        log.info(LogUtil.log("upFile","源文件。文件长度："+myFile.getSize()+",文件类型："+myFile.getContentType()+",文件原名："+myFile.getOriginalFilename()));

        String fileName = myFile.getOriginalFilename();
        //转义拆分重命名文件
        String[] strArr=fileName.split("\\.");
        String type = strArr[strArr.length-1];
        String key = IdUtil.simpleUUID()+"."+ type;
        //统一文件到日文件夹
        String month= DateUtil.today();
        key=month+"/"+key;
        return key;
    }

    /**
     * 获取文件路径
     * @param key
     * @return
     */
    private static String getFilePath(String key) {
        String filePath="";
        try {
            //过期时间，单位秒
            TemporarySignatureRequest req = new TemporarySignatureRequest(HttpMethodEnum.GET, 300);
            req.setBucketName(bucketName);
            req.setObjectKey(key);
            TemporarySignatureResponse res = obsClient.createTemporarySignature(req);

            filePath = res.getSignedUrl();

            if (!StringUtils.isEmpty(filePath)) {
                int index = filePath.indexOf("?");
                if (index > 0) {
                    filePath = filePath.substring(0, index);
                }
            }
        } catch (Exception ex) {
            if (ex instanceof ObsException){
                ObsException e = (ObsException)ex;
                log.error(StrConsts.CATCH_MESSAGE,ex);
                log.error(LogUtil.log(e.getMessage()));
            }else{
                log.error(StrConsts.CATCH_MESSAGE,ex);
                log.error(LogUtil.log(ex.getMessage()));
            }
        }
        return filePath;
    }

    /**
     * @Description  上传保单PDF文件
     * @param inputStream
     * @Date 2019/12/11 18:44
     * @Author wangkf
     * @return java.lang.String
    */
    public static String uploadFilePDF(InputStream inputStream) throws ObsException, IOException {
        String filePath="";
        try {
            String key = IdUtil.simpleUUID()+".pdf";
            //统一文件到日文件夹
            String month= DateUtil.today();
            key=month+"/"+key;

            HeaderResponse response = obsClient.putObject(bucketName, key, inputStream);
            filePath = getFilePath(key);
            log.info(LogUtil.log("upFile","上传obs文件："+filePath));
        }catch (Exception e) {
            log.error(StrConsts.CATCH_MESSAGE,e);
        }
        return filePath;
    }


    /**
     * 上传文件
     *
     * @param file
     */
    public static String uploadFile(File file) throws ObsException, IOException {
        if( null==file ){
            return "";
        }
        String filePath="";
        try {

            String fileName = file.getName();
            //转义拆分重命名文件
            String[] strArr=fileName.split("\\.");
            String type = strArr[strArr.length-1];
            String key = IdUtil.simpleUUID()+"."+ type;
            //统一文件到日文件夹
            String month= DateUtil.today();
            key=month+"/"+key;

            InputStream inputStream = new FileInputStream(file);
            HeaderResponse response = obsClient.putObject(bucketName, key, inputStream);
            filePath = getFilePath(key);
        }catch (Exception e) {
            log.error(StrConsts.CATCH_MESSAGE,e);
        }
        return filePath;
    }
}
